class Snake {
  // 表示蛇头的元素
  head: HTMLElement;
  // 表示蛇的身体
  bodies: HTMLCollection;
  // 获取蛇的容器
  element: HTMLElement;

  constructor() {
    this.element = document.getElementById('snake')!;
    this.head = document.querySelector('#snake > div') as HTMLElement;
    this.bodies = this.element.getElementsByTagName('div');
  }

  // 蛇头坐标
  // 获取XY坐标
  get X() {
    return this.head.offsetLeft;
  }

  get Y() {
    return this.head.offsetTop;
  }

  // 设置蛇头坐标
  set X(value: number) {
    // 如果新值旧值相同，则直接返回不再修改
    if (this.X === value) {
      return;
    }
    if (value < 0 || value > 290) {
      throw new Error('蛇撞墙了！')
    }
    // 阻止掉头
    if (this.bodies[1] && (this.bodies[1] as HTMLElement).offsetLeft === value) {
      value = value > this.X ? this.X - 10 : this.X + 10;
    }
    // 移动身体
    this.moveBody();
    this.head.style.left = value + 'px';
    // 检查有没有撞到自己
    this.checkHeadBody()
  }

  set Y(value: number) {
    // 如果新值旧值相同，则直接返回不再修改
    if (this.Y === value) {
      return;
    }
    if (value < 0 || value > 290) {
      throw new Error('蛇撞墙了！')
    }
    // 阻止掉头
    if (this.bodies[1] && (this.bodies[1] as HTMLElement).offsetTop === value) {
      value = value > this.Y ? this.Y - 10 : this.Y + 10;
    }
    // 移动身体
    this.moveBody();
    this.head.style.top = value + 'px';
    // 检查有没有撞到自己
    this.checkHeadBody()
  }

  // 增加身体方法
  addBody() {
    // 向element中添加div
    this.element.insertAdjacentHTML('beforeend', '<div id="snakeBody"></div>');
  }

  // 移动身体方法
  moveBody() {
    // 遍历身体
    for (let i = this.bodies.length - 1; i > 0; i--) {
      // 获取前边身体的位置
      let X = (this.bodies[i - 1] as HTMLElement).offsetLeft;
      let Y = (this.bodies[i - 1] as HTMLElement).offsetTop;

      // 设置到当前身体上
      (this.bodies[i] as HTMLElement).style.left = X + 'px';
      (this.bodies[i] as HTMLElement).style.top = Y + 'px';
    }
  }

  // 检查是否撞到了身体
  checkHeadBody(){
    for(let i = 1;i<this.bodies.length;i++){
      let bd = this.bodies[i] as HTMLElement
      if(this.X === bd.offsetLeft && this.Y === bd.offsetTop){
        throw new Error('撞到自己了!')
      }
    }
  }
}

export default Snake;